/*
 * TemperatureManager.cpp
 *
 * Created: 3/6/2013 11:42:18 PM
 *  Author: brodzki
 */ 

#define F_CPU 8000000UL // clock speed - 8Mhz (unsigned long)

#include "ThermometerHandler.h"
#include <util/delay.h>
#include <avr/sfr_defs.h>
#include <avr/io.h>
#include <stdlib.h>

void ThermometerHandler::disable_pull_up()
{
	pin_.unset_bit(bit_);
}

void ThermometerHandler::set_ddr(bool in)
{
	in ? ddr_.unset_bit(bit_) : ddr_.set_bit(bit_);
}

void ThermometerHandler::get_result(char *out)
{
	dtostrf(get_result(), 1, 2, out);
}

float ThermometerHandler::get_result()
{
	return ((float)get_low() + (get_high() * 256.0)) * 0.0625;
}

void ThermometerHandler::start_measurement()
{
	bool reset = reset_pulse();
		
	if(reset)
	{
		send_byte(0xCC);
		send_byte(0x44);
		_delay_ms(750);
		reset = reset_pulse();
		send_byte(0xCC);
		send_byte(0xBE);
		l_ = read_byte();
		h_ = read_byte();
		reset = reset_pulse();
	}
}

bool ThermometerHandler::reset_pulse()
{
	bool presence_impulse = false;
	disable_pull_up();
	set_ddr(false);
	_delay_us(500);
	set_ddr(true);
	_delay_us(45);
	
	if(bit_is_clear(*(pin_.address), bit_))
	{
		presence_impulse = true;
	}
	
	_delay_us(470);
	
	return presence_impulse;
}

void ThermometerHandler::send_bit(bool bit)
{
	set_ddr(false);
	_delay_us(5);
	
	if(bit)
	{
		set_ddr(true);
	}
	
	_delay_us(80);
	set_ddr(true);
}

bool ThermometerHandler::read_bit()
{
	bool result = false;
	
	set_ddr(false);
	_delay_us(2);
	set_ddr(true);
	_delay_us(15);
	
	if(bit_is_set(*(pin_.address), bit_))
	{
		result = true;
	}
	
	return result;
}

void ThermometerHandler::send_byte(char byte)
{
	unsigned char counter;
	unsigned char value_to_send;
	
	for(counter = 0; counter < 8; ++counter)
	{
		value_to_send = byte >> counter;
		value_to_send &= 0x01;
		send_bit(value_to_send);
	}
	_delay_us(100);
}

unsigned char ThermometerHandler::read_byte()
{
	unsigned char counter;
	unsigned char result = 0;
	
	for(counter = 0; counter < 8; ++counter)
	{
		if(read_bit())
		{
			result |= 0x01 << counter;
		}
		_delay_us(15);
	}
	
	return result;
}